package com.gjt.InternetAddress;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;

/**
 * Created with Intel IDEA.
 * InetAddress 类: 是（java.net.InetAddress）并且他的方法是 线程安全的
 *  方法： getHostName/getCanonicalHostName(): 返回String 包含主机名以及ip
 *        getAddress:返回byte[] ip地址
  *       getHostAddress: 返回String 包含主机名以及ip
 *        isReachable(int timeout):
 *        isReachable(NetworkInterface interface , int ttl , int timeout); 测试可达性
 *  IP地址的分类：
 *      测试方法  isAnyLocalAddress(): 通配地址可以匹配本地系统中的任何地址,如果有多个网络接口
 *              isLoopbackAddress(): 回送地址；ipv4(127.0.0.1)      ipv6 (：：1)
 *              isLinkLocalAddress(): ipv6的本地连接地址 帮助ipv6实现网络自配置，类似ipv4的dhcp； Router 不会把发送给本地连接的地址的包转发到本地子网以外
 *              isSiteLocalAddress(): ipv6本地网站地址 可以由Router在网站或者校园内转发，但不应转发到网站意外的
 *              isMulticastAddress(): 组播地址 224.0.0.0 - 239.255.255.255 将内容广播所有预定的计算机
 *              isMCGlobal(): 全球组播地址
 *              isMCNodeLocal(): 组织范围组播地址
 *              isMCLinkLocal(): 子网范围组播地址 发送到子网组播地址的的包只会在自己的子网内传输
 *              isMCSiteLocal(): 网站范围组播地址 发送到网站范围的包只会在本地网站内传输
 *              isMCOrgLocal(): 本地接口组播地址  发送到本地接口的地址的包不能发送到最初的网络接口以外
 * @Auther: gjt
 * @Date: 2024/3/20 23:43
 */
public class Internet {

    public static void main(String[] args) {

        /**
         * 注意：InterAddress 会缓存查找的结果，即使你为同一个主机建立新的InterAddress对象（不是一个安全操作）
         */

        /**
         * case 1: 使用 InterAddress 的静态方法获取 InetAddress类 显示域名的地址ip
         */

        try{
            InetAddress address = InetAddress.getByName("gjt1314yy.xyz");
            InetAddress address1 = InetAddress.getByName("152.136.138.218");
            System.out.println(address);
            System.out.println(address1.getHostName());
        }catch (UnknownHostException e){
            e.printStackTrace();
        }

        /**
         * case 2:获取域名的所有ip地址 百度域名可能有多个ip地址
         */
        try{
            InetAddress[] address = InetAddress.getAllByName("www.baidu.com");
            for (InetAddress inetAddress : address) {
                System.out.println(inetAddress);
            }
        }catch (UnknownHostException e){
            e.printStackTrace();
        }


        /**
         * case 3: 获取本机的ip 地址
         */
        try{
            InetAddress address = InetAddress.getLocalHost();
            System.out.println(address);
        }catch (UnknownHostException e){
            e.printStackTrace();
        }

        /**
         * case 4: 可以使用 getByAddress()为不存在的或者无法解析的主机创建地址（不一定保证主机一定存在或者不一定能正确地映射到ip地址）
         *       getByAddress(byte[] addr):依据ip
         *       getByAddress(String hostName, byte[] addr):依据主机名和ip
         */

        try{
            // 使用InetAddress前 检测该地址是否可以解析
            SecurityManager securityManager = new SecurityManager();
            securityManager.checkConnect("gjt1314yy.xyz",-1);

            byte[] addr = {(byte)152,(byte)136,(byte)138,(byte)218};
            // address 中不带有主机名
            InetAddress address = InetAddress.getByAddress(addr);
            // address 中带有主机名
            InetAddress address1 = InetAddress.getByAddress("gjt1314yy.xyz",addr);
            System.out.println(address);

            // 返回的是无符号的整数，值大于127 Java会当作负数
            byte[] address2 = address1.getAddress();
            //做法是将byte 提升为int 之后转换
            int arr = address2[0] < 0 ? address2[0] + 256 : address2[0];

            // 测试网络是否可达
            address.isReachable(3000);

        }catch (UnknownHostException e){
            e.printStackTrace();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }


    }
}
